package com.yong.ssj.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;

import org.apache.log4j.Logger;
import org.springframework.util.StringUtils;

/**
 * 日期时间处理工具类
 * 
 * @author
 * @since
 * 
 */
public class DateTimeUtils {

	// 日志处理
	private static final Logger logger = Logger.getLogger(DateTimeUtils.class);

	// 时区名称
	public static String zoneName = "GMT+8";

	// 默认格式化字符串
	public static String defaultFormatString = "yyyy-MM-dd HH:mm:ss";

	/**
	 * 字符串转换为日期
	 * 
	 * @param dateStr
	 * @param formatStr
	 * @return
	 */
	public static Date parseDate(String dateStr, String formatStr) {
		if (StringUtils.isEmpty(formatStr) || StringUtils.isEmpty(dateStr)) {
			return null;
		}
		try {
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(formatStr);
			simpleDateFormat.setTimeZone(TimeZone.getTimeZone(zoneName));
			return simpleDateFormat.parse(dateStr);
		} catch (ParseException e) {
		}
		return null;
	}

	/**
	 * 默认格式的转换字符串为日期
	 * 
	 * @param dateStr
	 * @return
	 */
	public static Date parseDate(String dateStr) {
		return parseDate(dateStr, defaultFormatString);
	}

	public static Date parseSimpleDate(String dateStr) {
		return parseDate(dateStr, "yyyy-MM-dd");
	}

	/**
	 * 日期格式化为字符串
	 * 
	 * @param date
	 * @param formatStr
	 * @return
	 */
	public static String formatDate(Date date, String formatStr) {
		if (date == null) {
			return null;
		}
		try {
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(formatStr);
			simpleDateFormat.setTimeZone(TimeZone.getTimeZone(zoneName));
			return simpleDateFormat.format(date);
		} catch (Exception e) {
			logger.info("日期格式化为字符串异常");
		}

		return null;
	}

	/**
	 * 默认格式的日期格式化为字符串
	 * 
	 * @param date
	 * @return
	 */
	public static String formatDate(Date date) {
		return formatDate(date, defaultFormatString);
	}

	/**
	 * 默认格式的日期格式化为字符串
	 * 
	 * @param date
	 * @return
	 */
	public static String formatDate(String date, String sourceFormat, String targetFormat) {
		return formatDate(parseDate(date, sourceFormat), targetFormat);
	}

	/**
	 * 返回年份
	 * 
	 * @param date
	 * @return
	 */
	public static int getYear(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.YEAR);
	}

	/**
	 * 返回月份
	 * 
	 * @param date
	 * @return
	 */
	public static int getMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.MONTH) + 1;
	}

	/**
	 * 返回月份
	 * 
	 * @param date
	 * @param add
	 * @return
	 */
	public static int getMonth(Date date, int add) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, add);
		return c.get(Calendar.MONTH) + 1;
	}

	/**
	 * 返回周
	 * 
	 * @param date
	 *            日期
	 * @return 返回周
	 */
	public static int getWeek(java.util.Date date) {
		java.util.Calendar c = java.util.Calendar.getInstance();
		c.setTime(date);
		return c.get(java.util.Calendar.WEEK_OF_YEAR);
	}

	/**
	 * 返回日份
	 * 
	 * @param date
	 * @return
	 */
	public static int getDay(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 返回小时
	 * 
	 * @param date
	 * @return
	 */
	public static int getHour(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * 返回分钟
	 * 
	 * @param date
	 * @return
	 */
	public static int getMinute(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.MINUTE);
	}

	/**
	 * 返回秒钟
	 * 
	 * @param date
	 * @return
	 */
	public static int getSecond(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.SECOND);
	}

	/**
	 * 返回毫秒
	 * 
	 * @param date
	 * @return
	 */
	public static long getMillis(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.getTimeInMillis();
	}

	/**
	 * 返回字符型日期
	 * 
	 * @param date
	 * @return
	 */
	public static String getDate(Date date) {
		return formatDate(date, "yyyyMMdd");
	}

	/**
	 * 返回字符型时间
	 * 
	 * @param date
	 * @return
	 */
	public static String getTime(Date date) {
		return formatDate(date, "HHmmss");
	}

	/**
	 * 返回字符型日期时间
	 * 
	 * @param date
	 * @return
	 */
	public static String getDateTime(Date date) {
		return formatDate(date, defaultFormatString);
	}

	/**
	 * 获取一天前的时间
	 * 
	 * @param dateFormat
	 * @return
	 */
	public static String getToday(String dateFormat) {
		Calendar cal = Calendar.getInstance();
		Date date = cal.getTime();
		if (dateFormat != null)
			return formatDate(date, dateFormat);
		return formatDate(date, defaultFormatString);
	}

	/**
	 * 获取一天前的时间
	 * 
	 * @param dateFormat
	 * @return
	 */
	public static String getYesterDay(String dateFormat) {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DATE, -1);
		Date date = cal.getTime();
		if (dateFormat != null)
			return formatDate(date, dateFormat);
		return formatDate(date, defaultFormatString);
	}

	/**
	 * 日期相加
	 * 
	 * @param date
	 * @param day
	 * @return
	 */
	public static Date addDate(Date date, int day) {
		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(getMillis(date) + ((long) day) * 24 * 3600 * 1000);
		return c.getTime();
	}

	/**
	 * 
	 * @param date
	 * @param formatStr
	 * @param day
	 * @return
	 */
	public static String addDate(Date date, String formatStr, int day) {
		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(getMillis(date) + ((long) day) * 24 * 3600 * 1000);
		return formatDate(c.getTime(), formatStr);
	}

	/**
	 * 日期相加
	 * 
	 * @param date
	 * @param day
	 * @return
	 */
	public static String addDate(String date, String formatStr, int day) {
		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(getMillis(parseDate(date, formatStr)) + ((long) day) * 24 * 3600 * 1000);
		return formatDate(c.getTime(), formatStr);
	}

	/**
	 * 月份相加
	 * 
	 * @param date
	 * @param add
	 * @return
	 */
	public static Date addMonth(Date date, int add) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, add);
		return c.getTime();
	}

	/**
	 * 获取一个月有多少天
	 * 
	 * @param year
	 * @param month
	 * @return
	 */
	public static int getDaysOfMonth(int year, int month) {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month - 1);
		int maxDate = cal.getActualMaximum(Calendar.DATE);
		return maxDate;
	}

	/**
	 * 获取指定周的开始日期
	 * 
	 * @param year
	 * @param week
	 * @return
	 */
	public static String getWeekStartDate(int year, int week) {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.WEEK_OF_YEAR, week);
		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		return formatDate(cal.getTime(), "yyyy/MM/dd");
	}

	/**
	 * 获取指定周的开始日期
	 * 
	 * @param year
	 * @param week
	 * @param formatStr
	 * @return
	 */
	public static String getWeekStartDate(int year, int week, String formatStr) {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.WEEK_OF_YEAR, week);
		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		return formatDate(cal.getTime(), formatStr);
	}

	/**
	 * 获取指定周的结束日期
	 * 
	 * @param year
	 * @param week
	 * @return
	 */
	public static String getWeekEndDate(int year, int week) {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.WEEK_OF_YEAR, week + 1);
		cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
		return formatDate(cal.getTime(), "yyyy/MM/dd");
	}

	/**
	 * 获取指定周的结束日期
	 * 
	 * @param year
	 * @param week
	 * @param formatStr
	 * @return
	 */
	public static String getWeekEndDate(int year, int week, String formatStr) {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.WEEK_OF_YEAR, week + 1);
		cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
		return formatDate(cal.getTime(), formatStr);
	}

	/**
	 * 获取当前年的最大周数
	 * 
	 * @param year
	 * @return
	 */
	public static int getMaxWeekNumOfYear(int year) {
		Calendar c = new GregorianCalendar();
		c.set(year, Calendar.DECEMBER, 31, 23, 59, 59);
		c.setFirstDayOfWeek(Calendar.MONDAY);
		c.setMinimalDaysInFirstWeek(7);
		return c.get(Calendar.WEEK_OF_YEAR);
	}

	/**
	 * 日期相减
	 * 
	 * @param date
	 * @param date1
	 * @return
	 */
	public static int diffDateForDay(Date date, Date date1) {
		return (int) ((getMillis(date) - getMillis(date1)) / (24 * 3600 * 1000));
	}

	/**
	 * 日期相减
	 * 
	 * @param date
	 * @param date1
	 * @return
	 */
	public static int diffDateForDay(String date, String date1, String format) {
		return (int) ((getMillis(parseDate(date, format)) - getMillis(parseDate(date1, format))) / (24 * 3600 * 1000));
	}

	/**
	 * 日期相减
	 * 
	 * @param date
	 * @param date1
	 * @return
	 */
	public static int diffDateForHour(Date date, Date date1) {
		return (int) ((getMillis(date) - getMillis(date1)) / (3600 * 1000));
	}

	/**
	 * 日期相减
	 * 
	 * @param date
	 * @param date1
	 * @return
	 */
	public static int diffDateForMinute(Date date, Date date1) {
		return (int) ((getMillis(date) - getMillis(date1)) / (60 * 1000));
	}

	/**
	 * 日期相减
	 * 
	 * @param date
	 * @param date1
	 * @return
	 */
	public static int diffDateForSecond(Date date, Date date1) {
		return (int) ((getMillis(date) - getMillis(date1)) / 1000);
	}

	public static String dateDiffInfo(Long second) {
		long nd = 24 * 60 * 60;// 一天的秒数
		long nh = 60 * 60;// 一小时的秒数
		long nm = 60;// 一分钟的秒数
		long day = second / nd;// 计算差多少天
		long hour = second % nd / nh;// 计算差多少小时
		long min = second % nd % nh / nm;// 计算差多少分钟
		long sec = second % nd % nh % nm;// 计算差多少秒
		// 输出结果
		StringBuffer result = new StringBuffer();
		if (day > 0)
			result.append(day + "天");
		if (hour > 0)
			result.append(hour + "小时");
		if (min > 0)
			result.append(min + "分");
		if (sec > 0)
			result.append(sec + "秒");
		return result.toString();
	}

	public static String dateDiffInfo(Date before, Date after) {
		long nd = 1000 * 24 * 60 * 60;// 一天的毫秒数
		long nh = 1000 * 60 * 60;// 一小时的毫秒数
		long nm = 1000 * 60;// 一分钟的毫秒数
		long ns = 1000;// 一秒钟的毫秒数
		long diff;
		// 获得两个时间的毫秒时间差异
		diff = after.getTime() - before.getTime();
		long day = diff / nd;// 计算差多少天
		long hour = diff % nd / nh;// 计算差多少小时
		long min = diff % nd % nh / nm;// 计算差多少分钟
		long sec = diff % nd % nh % nm / ns;// 计算差多少秒
		// 输出结果
		StringBuffer result = new StringBuffer();
		if (day > 0)
			result.append(day + "天");
		if (hour > 0)
			result.append(hour + "小时");
		if (min > 0)
			result.append(min + "分");
		if (sec > 0)
			result.append(sec + "秒");
		return result.toString();
	}

	public static int getAllWeeks(Long year) throws Exception {
		Calendar calendar = Calendar.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		calendar.setTime(sdf.parse(year + "-12-31"));
		int week = calendar.get(Calendar.WEEK_OF_YEAR);
		if (week != 53) {
			week = 52;
		}
		return week;
	}

	/**
	 * 获取考核周期
	 * 
	 * @param date
	 * @return
	 */
	public static int getInspectionPeriod(Date date) {
		int day = DateTimeUtils.getDay(date);
		int order = 0;
		if (1 <= day && day <= 7) {
			order = 1;
		} else if (8 <= day && day <= 14) {
			order = 2;
		} else if (15 <= day && day <= 21) {
			order = 3;
		} else if (day >= 22) {
			order = 4;
		}
		return order;
	}

	/**
	 * 最近一周的日期（不包含当前日期）
	 * 
	 * @return
	 */
	public static List<Date> dateLink() {
		List<Date> dateLink = new ArrayList<Date>();
		List<Date> curLink = new ArrayList<Date>();
		Calendar calendar = Calendar.getInstance();
		for (int i = 0; i < 7; i++) {
			calendar.add(Calendar.DATE, -1);
			dateLink.add(calendar.getTime());
		}
		for (int i = 6; i >= 0; i--) {
			Date date = dateLink.get(i);
			curLink.add(date);
		}
		return curLink;
	}

	/**
	 * 若干月连续
	 * 
	 * @param start
	 * @param monthNum
	 * @return
	 */
	public static List<Date> getMonthLink(Date start, int monthNum) {
		List<Date> dateLink = new ArrayList<Date>();
		if (start == null) {
			start = new Date();
		}
		if (monthNum >= 0) {
			for (int i = 0; i < monthNum; i++) {
				dateLink.add(addMonth(start, i));
			}
		} else {
			for (int i = monthNum + 1; i <= 0; i++) {
				dateLink.add(addMonth(start, i));
			}
		}
		return dateLink;
	}

	/**
	 * 最近一周的日期（不包含当前日期）
	 * 
	 * @return
	 */
	public static List<Date> getDayLink(Date start, int dayNum) {
		List<Date> dateLink = new ArrayList<Date>();
		if (start == null) {
			start = new Date();
		}
		if (dayNum >= 0) {
			for (int i = 0; i < dayNum; i++) {
				dateLink.add(addDate(start, i));
			}
		} else {
			for (int i = dayNum + 1; i <= 0; i++) {
				dateLink.add(addDate(start, i));
			}
		}

		return dateLink;
	}

	/**
	 * 根据当前日期获取特定日期
	 * 
	 * @param data
	 * @return
	 * @throws ParseException
	 */
	public static Date getWeekDayByCur(int data) throws ParseException {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, data);
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
		Date hTime = dateFormat.parse(dateFormat.format(calendar.getTime()));// 昨天的日期
		return hTime;
	}

}
